package com.gsk.test123.config;


import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

/**
 * 数据源配置
 *
 * @author
 * @ClassName DataSourceConfig
 * @Description
 * @date 2018年2月27日 下午1:21:39
 */
@Configuration
@MapperScan("com.gsk.test123.mapper")
@EnableTransactionManagement
public class DataSourceConfig {

    @Autowired
    private DataSourceProperties properties;  // (2)

//    @Value("${spring.datasource.druid.filters}")
//    private String filters;
//
//    @Value("${spring.datasource.druid.initial-size}")
//    private Integer initialSize;
//
//    @Value("${spring.datasource.druid.min-idle}")
//    private Integer minIdle;
//
//    @Value("${spring.datasource.druid.max-active}")
//    private Integer maxActive;
//
//    @Value("${spring.datasource.druid.max-wait}")
//    private Integer maxWait;
//
//    @Value("${spring.datasource.druid.time-between-eviction-runs-millis}")
//    private Long timeBetweenEvictionRunsMillis;
//
//    @Value("${spring.datasource.druid.min-evictable-idle-time-millis}")
//    private Long minEvictableIdleTimeMillis;
//
//    @Value("${spring.datasource.druid.validation-query}")
//    private String validationQuery;
//
//    @Value("${spring.datasource.druid.test-while-idle}")
//    private Boolean testWhileIdle;
//
//    @Value("${spring.datasource.druid.test-on-borrow}")
//    private boolean testOnBorrow;
//
//    @Value("${spring.datasource.druid.test-on-return}")
//    private boolean testOnReturn;
//
//    @Value("${spring.datasource.druid.pool-prepared-statements}")
//    private boolean poolPreparedStatements;
//
//    @Value("${spring.datasource.druid.max-pool-prepared-statement-per-connection-size}")
//    private Integer maxPoolPreparedStatementPerConnectionSize;

//    /**
//     * 根据数据源创建SqlSessionFactory
//     */
//    @Bean(name = "masterSqlSessionFactory")
//    public SqlSessionFactory sqlSessionFactory111(@Qualifier("dynamicDataSource") DynamicDataSource dynamicDataSource) throws Exception {
//        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
//        bean.setDataSource(dynamicDataSource);// 指定数据源(这个必须有，否则报错)
//        // 下边两句仅仅用于*.xml文件，如果整个持久层操作不需要使用到xml文件的话（只用注解就可以搞定），则不加
//        // bean.setTypeAliasesPackage(env.getProperty("mybatis.typeAliasesPackage"));// 指定基包
//        //  bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(env.getProperty("mybatis.mapperLocations")));//
//
////		bean.setConfigLocation(new ClassPathResource("mybatisConfig.xml"));
////        bean.setTypeAliasesPackage(ProjectConstant.PROCESSINGRES_MODEL_PACKAGE);
////        //分页插件
////        PageHelper pageHelper = new PageHelper();
////        Properties properties = new Properties();
////        properties.setProperty("reasonable", "true");
////        properties.setProperty("supportMethodsArguments", "true");
////        properties.setProperty("returnPageInfo", "check");
////        properties.setProperty("params", "count=countSql");
////        pageHelper.setProperties(properties);
////
////        //添加插件
////        bean.setPlugins(new Interceptor[]{pageHelper});
//
//        //添加XML目录
//        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
//        try {
//            bean.setMapperLocations(resolver.getResources("classpath:mapper/*.xml"));
////			bean.setMapperLocations(resolver.getResources("classpath:mapper/*/*.xml"));
//            return bean.getObject();
//        } catch (Exception e) {
//            e.printStackTrace();
//            throw new RuntimeException(e);
//        }
//
//    }

    @Bean(name = "master")
    @Qualifier("master")
    @ConfigurationProperties(prefix = "spring.datasource.master")
    public DataSource dataSource1() {
        System.out.println("主配");
        return new DruidDataSource();
    }

    @Bean(name = "slave")
    @Qualifier("slave")
    @ConfigurationProperties(prefix = "spring.datasource.slave")
    public DataSource dataSource2() throws SQLException {
        System.out.println("从配");
//        DruidDataSource dataSource = new DruidDataSource();
//        dataSource.setFilters(filters);
//        dataSource.setUrl(properties.getUrl());
//        dataSource.setDriverClassName(properties.getDriverClassName());
//        dataSource.setUsername(properties.getUsername());
//        dataSource.setPassword(properties.getPassword());
//        dataSource.setInitialSize(initialSize);
//        dataSource.setMinIdle(minIdle);
//        dataSource.setMaxActive(maxActive);
//        dataSource.setMaxWait(maxWait);
//        dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
//        dataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
//        dataSource.setValidationQuery(validationQuery);
//        dataSource.setTestWhileIdle(testWhileIdle);
//        dataSource.setTestOnBorrow(testOnBorrow);
//        dataSource.setTestOnReturn(testOnReturn);
//        dataSource.setPoolPreparedStatements(poolPreparedStatements);
//        dataSource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
//        return dataSource;
        return new DruidDataSource();
    }

    @Bean(name = "dynamicDataSource")
    @Primary    //优先使用，多数据源
    public DynamicDataSource dataSource() throws SQLException{
        DynamicDataSource dynamicDataSource = new DynamicDataSource();
        DataSource master = dataSource1();
        DataSource slave = dataSource2();
        //设置默认数据源
        dynamicDataSource.setDefaultTargetDataSource(master);
        //配置多数据源
        Map<Object, Object> map = new HashMap<>();
        map.put(DataSourceType.Master.getName(), master);    //key需要跟ThreadLocal中的值对应
        map.put(DataSourceType.Slave.getName(), slave);
        dynamicDataSource.setTargetDataSources(map);
        return dynamicDataSource;
    }

    @Bean
    public SqlSessionFactory sqlSessionFactory(@Qualifier("dynamicDataSource") DynamicDataSource dynamicDataSource) throws Exception {
        MybatisSqlSessionFactoryBean fb = new MybatisSqlSessionFactoryBean();
        fb.setDataSource(dynamicDataSource);
        fb.setTypeAliasesPackage("com.gsk.test123.entity");
        fb.setMapperLocations(
                new PathMatchingResourcePatternResolver().getResources("classpath:/mapper/*Mapper.xml"));
        return fb.getObject();
    }

    /**
     * 配置事务管理器
     */
    @Bean
    public DataSourceTransactionManager transactionManager(
            @Qualifier("dynamicDataSource") DynamicDataSource dataSource) throws Exception {
        return new DataSourceTransactionManager(dataSource);
    }
}
